//
// Created by zzx on 2022/10/10.
//

#ifndef QTCREATERHELLO_CALCULATE_H
#define QTCREATERHELLO_CALCULATE_H

#include <stack>
#include <cstring>
#include <iostream>

namespace std {

class Calculate {
public:
    int level[130];
    string s;
    stack<char>op;
    stack<double>nums;

    bool calOnce() {
        if (op.size() < 1 || nums.size() < 2) {
            return false;
        }
        char o = op.top();
        op.pop();
        auto r = nums.top();
        nums.pop();
        auto l = nums.top();
        nums.pop();
        double t;
        if (o == '-') {
            t = l - r;
        } else if (o == '+') {
            t = l + r;
        } else if (o == '*') {
            t = l * r;
        } else {
            if (r == 0) {
                return false;
            }
            t = l / r;
        }
        nums.push(t);
        return true;
    }

    double Solve(string s) {
        memset(level, 0, sizeof level);
        level['+'] = 1;
        level['-'] = 1;
        level['*'] = 2;
        level['/'] = 2;
        level['('] = 0;
        for (int i = 0; i < s.size(); i++){
            char c = s[i];
            if (c == '(') {
                op.push(c);
            } else if (c == ')') {
                if (op.size() == 0) {
                    return 0;
                }
                char top = op.top();
                while (top != '(') {
                    auto ret = calOnce();
                    if (!ret) {
                        return 0;
                    }
                    if (op.size() == 0) {
                        return 0;
                    }
                    top = op.top();
                }
                op.pop();
            } else if (isdigit(c)) {
                int num = c - '0';
                i++;
                while (i < s.size() && isdigit(s[i])) {
                    num = num * 10 + (s[i] - '0');
                    i++;
                }
                nums.push(num);
                i--;
            } else {
                while (!op.empty() && level[c] <= level[op.top()]) {
                    auto ret = calOnce();
                    if (ret == false) {
                        return 0;
                    }
                }
                op.push(c);
            }
        }
        while (nums.size() > 1) {
            auto ret = calOnce();
            if (ret == false) {
                return 0;
            }
        }
        return nums.top();
    }
};

}


#endif //QTCREATERHELLO_CALCULATE_H
